<!-- subpkg_consult/room/index.vue -->
<script lang="ts" setup>
import { useUserStore } from "@/stores/user";
import RoomStatus from "./components/room-status.vue";
import { io } from "socket.io-client";
import { orderDetailApi } from "@/apis/consult";
import { nextTick, ref } from "vue";
import type { OrderDetail } from "@/types/consult";
import type { MsgData, MsgItem, SendChatMsgParams } from "@/types/room";
import PatientInfo from "./components/patient-info.vue";
import NotifyInfo from "./components/notify-info.vue";
import MessageInfo from "./components/message-info.vue";
import PrescriptionInfo from "./components/prescription-info.vue";
import { uploadImageApi } from "@/apis/user";

// orderId=7092144021409792&payResult=true&type=2
const pageParams = defineProps<{
  orderId: string;
  payResult: "true" | "false";
  type: string;
}>();
console.log(pageParams);
// 支付失败(放弃支付)
if (pageParams.payResult === "false") {
  uni.showToast({ title: "支付异常", icon: "error" });
  setTimeout(() => {
    // 关闭所有页面，打开个人中心
    uni.reLaunch({ url: "/pages/my/index" });
  }, 2000);
}

// 1.1 WebSocket 连接
const store = useUserStore();
const socket = io("https://consult-api.itheima.net", {
  auth: { token: `Bearer ${store.token}` },
  query: { orderId: pageParams.orderId },
  transports: ["websocket", "polling"],
  timeout: 5000,
});
console.log("socket", {
  auth: { token: `Bearer ${store.token}` },
  query: { orderId: pageParams.orderId },
  transports: ["websocket", "polling"],
  timeout: 5000,
});

// webSocket   双向连接
// socket.on()      接收消息(服务器自动下发，类似自动化的 GET 请求，主要做渲染处理)
// socket.emit()    发送消息(自己发送给服务器，类似 POST 请求，提交表单)

socket.on("connect", () => {
  // 建立连接成功
  console.log("连接建立成功");
});

socket.on("error", (event) => {
  // 错误异常消息
  console.log("出现错误");
});

socket.on("disconnect", () => {
  // 已经断开连接
  console.log("断开连接");
});

const orderDetail = ref({} as OrderDetail);
const getDetail = async () => {
  const res = await orderDetailApi(pageParams.orderId);
  orderDetail.value = res;
};
getDetail();

// 1.2  问诊订单状态
socket.on("statusChange", () => {
  getDetail();
});

// 1.3 接收消息
// 消息列表
const messageList = ref<MsgItem[]>([]);
// 1.3.1 消息列表
socket.on("chatMsgList", async (res: MsgData) => {
  // 没有返回数据
  if (res.code !== 10000) return;
  // 提取列表数据
  if (res.data?.length) {
    // console.log(res.data[0].items)
    // 后端对消息进行了分段，渲染时要遍历所有分段
    res.data.forEach((item) => {
      // 把每个分段的消息都追加到数组中
      messageList.value.push(
        // 按日期分段
        {
          createTime: item.createTime!,
          msg: {
            content: item.createTime,
          },
          msgType: 31,
        },
        // 分段的聊天数据
        ...item.items!
      );
    });
  }
  await nextTick();
  // 设置为最后一项的 id，让滚动条滚动到最后面
  activeIndexText.value = `item-${messageList.value.length - 1}`;
  console.log("历史消息：", messageList.value);
});

// 1.3.4 文字/图片消息
socket.on("receiveChatMsg", async (message: MsgItem) => {
  // 通知后端当前消息已读
  socket.emit("updateMsgStatus", message.id);
  // 追加到数组中渲染
  messageList.value.push(message);
  // 等待前面的数据和视图更新完成，再往后执行任务
  await nextTick();
  // 设置为最后一项的 id，让滚动条滚动到最后面
  activeIndexText.value = `item-${messageList.value.length - 1}`;
  console.log("总的消息：", messageList.value);
});

const gotoIndexPage = () => {
  uni.switchTab({
    url: "/pages/index/index",
  });
};

// 输入框消息
const textMessage = ref("");
// 发送消息
const sendMessage = () => {
  // 非空判断
  if (textMessage.value.trim() === "") {
    return uni.showToast({ title: "请输入问题", icon: "none" });
  }
  // 通过 WebSocket 发送消息（注意：这里不是 POST 请求）
  socket.emit("sendChatMsg", {
    from: store.userId, // 患者 id
    to: orderDetail.value.docInfo.id, // 医生 id
    msgType: 1, // 文字类型
    msg: {
      content: textMessage.value, // 消息内容
    },
  } as SendChatMsgParams);
  // 清空表单
  textMessage.value = "";
};

// 发送图片
const sendImage = async () => {
  // 1. 选取图片
  const res = await uni.chooseImage({ count: 1 });
  // 如果有图片
  if (res.tempFilePaths[0]) {
    // 2. 上传图片
    const imageInfo = await uploadImageApi(res.tempFilePaths[0]);
    // 3. 发送图片消息
    socket.emit("sendChatMsg", {
      from: store.userId, // 患者/用户 id
      to: orderDetail.value.docInfo.id, // 医生 id
      msgType: 4, // 4图片类型
      msg: {
        picture: imageInfo,
      },
    } as SendChatMsgParams);
  }
};

// 设置滚动位置，值应为某子元素id（id不能以数字开头）
const activeIndexText = ref("");
</script>

<template>
  <view class="room-page">
    <RoomStatus
      v-if="orderDetail.status"
      :status="orderDetail.status"
      :status-value="orderDetail.statusValue"
      :countdown="orderDetail.countdown"
    />
    <scroll-view
      refresher-enabled
      refresher-background="#f2f2f2"
      scroll-y
      :scroll-into-view="activeIndexText"
      style="flex: 1; overflow: hidden"
    >
      <view
        class="message-container"
        v-for="(item, index) in messageList"
        :key="item.id"
        :id="`item-${index}`"
      >
        <!-- 此处将来填充更多代码... -->
        <!-- 1.3.2 患者消息 -->
        <PatientInfo
          v-if="item.msgType === 21"
          :info="item.msg?.consultRecord!"
        />
        <!-- 
            21	患者信息
            22	处方信息
            23	未提交评价
            24	已提交评价
            31	普通通知
            32	温馨提示
            33	取消订单
            4	图片消息
            1	文字消息
          -->
        <PrescriptionInfo
          v-else-if="item.msgType === 22"
          :info="item.msg?.prescription!"
        />
        <view v-else-if="item.msgType === 23">未提交评价</view>
        <view v-else-if="item.msgType === 24">已提交评价</view>
        <!-- 1.3.3 通知消息 -->
        <NotifyInfo
          v-else-if="[31,32,33].includes(item.msgType!)"
          :type="item.msgType"
        >
          {{ item.msg?.content }}
        </NotifyInfo>
        <!-- 1.3.4 文字/图片消息 -->
        <MessageInfo
          v-else-if="[4,1].includes(item.msgType!)"
          :info="item"
          :type="item.msgType"
        ></MessageInfo>
      </view>
    </scroll-view>

    <!-- 发送消息 -->
    <view class="message-bar">
      <template v-if="orderDetail.status <= 3">
        <!-- 
        订单状态：1待支付2待接诊3咨询中4已完成5已取消/药品订单10待支付11待发货12待收货13已完成14已取消 
         非咨询状态，都禁用输入框
        -->
        <uni-easyinput
          :disabled="orderDetail.status !== 3"
          :clearable="false"
          :input-border="false"
          placeholder-style="font-size: 32rpx; color: #c3c3c5;"
          placeholder="问医生"
          v-model="textMessage"
          @confirm="sendMessage"
        />
        <view class="image-button">
          <uni-icons
            @click="sendImage"
            size="40"
            color="#979797"
            type="image"
          ></uni-icons>
        </view>
      </template>
      <button @click="gotoIndexPage" v-else class="uni-button">
        咨询其它医生
      </button>
    </view>
  </view>
</template>

<style lang="scss">
@import "./index.scss";
</style>
